﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Cost.Models;
using NBlock.MVCExtensions;
using NBlock.Components.Excel;
using Cost.Services;

namespace Cost.Controllers
{
    public class DishController : Controller
    {
        #region 构造函数
        private readonly ICostRepository<Dish> dishRepository;
        private readonly ICostRepository<DishMaterial> dishMaterialRepository;
        private readonly ICostRepository<Material> materialRepository;
        private readonly MaterialService materialService;
        private readonly DishService dishService;
        private readonly IExcelImporter excelImporter;

        public DishController(ICostRepository<Dish> dishRepository,
            ICostRepository<DishMaterial> dishMaterialRepository,
            ICostRepository<Material> materialRepository,
            MaterialService materialService,
            IExcelImporter excelImporter, DishService dishService)
        {
            this.dishRepository = dishRepository;
            this.dishMaterialRepository = dishMaterialRepository;
            this.materialRepository = materialRepository;
            this.materialService = materialService;
            this.dishService = dishService;
            this.excelImporter = excelImporter;
        }
        #endregion

        public ActionResult Index()
        {
            return View();
        }

        public ActionResult Edit(string Id)
        {
            var data = dishService.GetDish(Id);
            ViewBag.MaterialList = dishService.GetDishMaterials(Id);
            return View(data);
        }

        [HttpPost]
        public JsonResult Save(string Id, IList<DishMaterial> MaterialList)
        {
            var data = dishRepository.Find(Id) ?? new Dish();
            TryUpdateModel(data);
            var ItemDesc = string.Empty;

            // 先删除所有子表，再保持所有子表数据
            dishMaterialRepository.DeleteAll(m => m.DishId == data.Id);
            if (MaterialList != null)
            {
                foreach (var m in MaterialList)
                {
                    m.DishId = data.Id;
                    if (materialRepository.IsExist(t => t.Id == m.Id))
                        m.MaterialId = m.Id;
                    ItemDesc += string.Format("{0}({1}g)，", m.Name, m.Weight);
                    dishMaterialRepository.Insert(m);
                }
            }
            data.ItemDesc = ItemDesc.Trim('，');
            dishRepository.Save(data);
            return Json(nbAjaxMessage.Successful);
        }

        [HttpPost]
        public JsonResult Delete(string Id)
        {
            dishRepository.Delete(Id);
            dishMaterialRepository.DeleteAll(m => m.DishId == Id);
            return Json(nbAjaxMessage.Successful);
        }

        [HttpPost]
        public JsonResult DeleteAll(string Ids)
        {
            var items = Ids.Split(',');
            dishRepository.DeleteAll(d => items.Contains(d.Id));
            return Json(nbAjaxMessage.Successful);
        }

        [HttpPost]
        public JsonResult List(string IsFilter, nbPageInfo pager, nbSearchCondition where)
        {
            var pageData = dishRepository.GetPageable(pager, where);
            var data = pager.ToGridData(pageData);
            return Json(data);
        }

        #region LookUp
        public ActionResult LookUp()
        {
            return View();
        }
        #endregion

        #region 数据导入
        public ActionResult Import(string excelKey)
        {
            ViewBag.TemplateUrl = excelImporter.GetExcelTemplateUrl(excelKey);
            ViewBag.ExcelKey = excelKey;
            return View();
        }

        [HttpPost]
        public nbFileUploadJsonResult Import(HttpPostedFileBase file, string ExcelKey, string UpdateMode)
        {
            try
            {
                // 保留导入文档，以便后续检查
                var path = Server.MapPath("~/Upload/") + System.IO.Path.GetFileName(file.FileName).Replace(".", "_" + DateTime.Now.ToString("yyyyMMddHHmmss") + ".");
                file.SaveAs(path);

            }
            catch (Exception ex)
            {
                // TODO 记录日志
            }

            var notMaterial = "";
            var data = excelImporter.Import(file, ExcelKey);
            foreach (var row in data.RepeatData.Rows)
            {
                var item = row.ToEntity<DishExcelModel>();
                var dishItem = dishRepository.Find(m => m.Name == item.Name);
                if (dishItem != null)
                {
                    dishItem.Category = item.Category;
                    dishItem.MainMaterialType = item.MainMaterialType;
                }
                else
                {
                    dishItem = new Dish
                    {
                        Code = item.Code,
                        Name = item.Name,
                        Category = item.Category,
                        MainMaterialType = item.MainMaterialType,
                    };
                }
                var ItemDesc = "";
                var details = new List<DishMaterial>();

                // 保存子表数据
                dishMaterialRepository.DeleteAll(m => m.DishId == dishItem.Id);
                if (!string.IsNullOrWhiteSpace(item.MainMaterialName))
                {
                    var material = materialRepository.Find(m => m.Name == item.MainMaterialName);
                    if (material != null)
                    {
                        var mainMaterial = new DishMaterial
                        {
                            Category = material.Category,
                            Code = material.Code,
                            NeedProcess = material.NeedProcess,
                            CurrentPrice = materialService.GetMaterialPrice(material.Id, needProcess: material.NeedProcess),
                            DishId = dishItem.Id,
                            MaterialId = material.Id,
                            Name = material.Name,
                            Weight = item.MainMaterialWeight,
                            Unit = material.Unit,
                        };
                        dishMaterialRepository.Insert(mainMaterial);
                        if (mainMaterial.Category != dishItem.MainMaterialType)
                        {
                            dishItem.MainMaterialType = mainMaterial.Category;
                        }
                        ItemDesc += string.Format("{0}({1}g)，", mainMaterial.Name, mainMaterial.Weight);
                        details.Add(mainMaterial);
                    }
                    else
                    {
                        // Todo 提示用户，找不到指定品名名称的品名
                        notMaterial += "," + item.MainMaterialName;
                        continue;
                    }
                }

                // 辅料一
                if (!string.IsNullOrWhiteSpace(item.Material1Name))
                {
                    var material = materialRepository.Find(m => m.Name == item.Material1Name);
                    if (material != null)
                    {
                        var Material1 = new DishMaterial
                        {
                            Category = material.Category,
                            Code = material.Code,
                            NeedProcess = material.NeedProcess,
                            CurrentPrice = materialService.GetMaterialPrice(material.Id, material.NeedProcess),
                            DishId = dishItem.Id,
                            MaterialId = material.Id,
                            Name = material.Name,
                            Weight = item.Material1Weight,
                            Unit = material.Unit,
                        };
                        dishMaterialRepository.Insert(Material1);

                        ItemDesc += string.Format("{0}({1}g)，", Material1.Name, Material1.Weight);
                        details.Add(Material1);
                    }
                    else
                    {
                        // Todo 提示用户，找不到指定品名名称的品名
                        notMaterial += "," + item.Material1Name;
                        continue;
                    }
                }

                // 辅料二
                if (!string.IsNullOrWhiteSpace(item.Material2Name))
                {
                    var material = materialRepository.Find(m => m.Name == item.Material2Name);
                    if (material != null)
                    {
                        var Material2 = new DishMaterial
                        {
                            Category = material.Category,
                            Code = material.Code,
                            NeedProcess = material.NeedProcess,
                            CurrentPrice = materialService.GetMaterialPrice(material.Id, material.NeedProcess),
                            DishId = dishItem.Id,
                            MaterialId = material.Id,
                            Name = material.Name,
                            Weight = item.Material2Weight,
                            Unit = material.Unit,
                        };
                        dishMaterialRepository.Insert(Material2);

                        ItemDesc += string.Format("{0}({1}g)，", Material2.Name, Material2.Weight);
                        details.Add(Material2);
                    }
                    else
                    {
                        // Todo 提示用户，找不到指定品名名称的品名
                        notMaterial += "," + item.Material2Name;
                        continue;
                    }
                }

                // 辅料三
                if (!string.IsNullOrWhiteSpace(item.Material3Name))
                {
                    var material = materialRepository.Find(m => m.Name == item.Material3Name);
                    if (material != null)
                    {
                        var Material3 = new DishMaterial
                        {
                            Category = material.Category,
                            Code = material.Code,
                            NeedProcess = material.NeedProcess,
                            CurrentPrice = materialService.GetMaterialPrice(material.Id, material.NeedProcess),
                            DishId = dishItem.Id,
                            MaterialId = material.Id,
                            Name = material.Name,
                            Weight = item.Material3Weight,
                            Unit = material.Unit,
                        };
                        dishMaterialRepository.Insert(Material3);

                        ItemDesc += string.Format("{0}({1}g)，", Material3.Name, Material3.Weight);
                        details.Add(Material3);
                    }
                    else
                    {
                        // Todo 提示用户，找不到指定品名名称的品名
                        notMaterial += "," + item.Material3Name;
                        continue;
                    }
                }

                // 辅料四
                if (!string.IsNullOrWhiteSpace(item.Material4Name))
                {
                    var material = materialRepository.Find(m => m.Name == item.Material4Name);
                    if (material != null)
                    {
                        var Material3 = new DishMaterial
                        {
                            Category = material.Category,
                            Code = material.Code,
                            NeedProcess = material.NeedProcess,
                            CurrentPrice = materialService.GetMaterialPrice(material.Id, material.NeedProcess),
                            DishId = dishItem.Id,
                            MaterialId = material.Id,
                            Name = material.Name,
                            Weight = item.Material3Weight,
                            Unit = material.Unit,
                        };
                        dishMaterialRepository.Insert(Material3);

                        ItemDesc += string.Format("{0}({1}g)，", Material3.Name, Material3.Weight);
                        details.Add(Material3);
                    }
                    else
                    {
                        // Todo 提示用户，找不到指定品名名称的品名
                        notMaterial += "," + item.Material4Name;
                        continue;
                    }
                }

                // 辅料五
                if (!string.IsNullOrWhiteSpace(item.Material5Name))
                {
                    var material = materialRepository.Find(m => m.Name == item.Material5Name);
                    if (material != null)
                    {
                        var Material3 = new DishMaterial
                        {
                            Category = material.Category,
                            Code = material.Code,
                            NeedProcess = material.NeedProcess,
                            CurrentPrice = materialService.GetMaterialPrice(material.Id, material.NeedProcess),
                            DishId = dishItem.Id,
                            MaterialId = material.Id,
                            Name = material.Name,
                            Weight = item.Material3Weight,
                            Unit = material.Unit,
                        };
                        dishMaterialRepository.Insert(Material3);

                        ItemDesc += string.Format("{0}({1}g)，", Material3.Name, Material3.Weight);
                        details.Add(Material3);
                    }
                    else
                    {
                        // Todo 提示用户，找不到指定品名名称的品名
                        notMaterial += "," + item.Material5Name;
                        continue;
                    }
                }
                dishItem.ItemDesc = ItemDesc.TrimEnd('，');
                dishItem.Cost = dishService.GetDishCost(dishItem.Id, details);
                dishRepository.Save(dishItem);
            }
            return new nbFileUploadJsonResult { Data = nbAjaxMessage.Successful };
        }
        #endregion
    }

    /// <summary>
    /// 匹配Excel导入的菜肴对象
    /// </summary>
    public class DishExcelModel
    {
        /// <summary>
        /// 编号
        /// </summary>
        public string Code { get; set; }
        /// <summary>
        /// 菜谱名称
        /// </summary>
        public string Name { get; set; }
        /// <summary>
        /// 分类
        /// </summary>
        public string MainMaterialType { get; set; }
        /// <summary>
        /// 类别
        /// </summary>
        public string Category { get; set; }
        /// <summary>
        /// 主料名称
        /// </summary>
        public string MainMaterialName { get; set; }
        /// <summary>
        /// 主料克数
        /// </summary>
        public decimal MainMaterialWeight { get; set; }
        /// <summary>
        /// 辅料一名称
        /// </summary>
        public string Material1Name { get; set; }
        /// <summary>
        /// 辅料一克数
        /// </summary>
        public decimal Material1Weight { get; set; }
        /// <summary>
        /// 辅料二名称
        /// </summary>
        public string Material2Name { get; set; }
        /// <summary>
        /// 辅料二克数
        /// </summary>
        public decimal Material2Weight { get; set; }
        /// <summary>
        /// 辅料三名称
        /// </summary>
        public string Material3Name { get; set; }
        /// <summary>
        /// 辅料三克数
        /// </summary>
        public decimal Material3Weight { get; set; }

        /// <summary>
        /// 辅料四名称
        /// </summary>
        public string Material4Name { get; set; }
        /// <summary>
        /// 辅料四克数
        /// </summary>
        public decimal Material4Weight { get; set; }

        /// <summary>
        /// 辅料五名称
        /// </summary>
        public string Material5Name { get; set; }
        /// <summary>
        /// 辅料五克数
        /// </summary>
        public decimal Material5Weight { get; set; }
    }
}
